package com.ohuang.util_h.activityInterceptor;

import android.content.Intent;
import android.os.Build;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * activity跳转拦截
 */
public class ActivityInterceptor {
    public static final String TAG = "ActivityInterceptor";


    private static boolean isHooked = false;

    private static Object mObject = null;

    private static IntentInterceptor startActivityInterceptor = null;


    public static void setStartActivityInterceptor(IntentInterceptor startActivityInterceptor) {
        ActivityInterceptor.startActivityInterceptor = startActivityInterceptor;
    }

    /**
     * 拦截
     */
    public synchronized static void hook() {
        if (isHooked) {
            return;
        }
        isHooked = true;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                Class<?> aClass = Class.forName("android.app.ActivityTaskManager");
                Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityTaskManagerSingleton");
                field_IActivityTaskManagerSingleton.setAccessible(true);
                Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);

                Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                field_mInstance.setAccessible(true);
                Method method_get = aClass_Singleton.getDeclaredMethod("get");
                Object mInstant = method_get.invoke(iActivityTaskManagerSingleton);
                mObject = mInstant;
                Class<?> aClass_IActivityTaskManager = Class.forName("android.app.IActivityTaskManager");
                Object mInstantProxy = Proxy.newProxyInstance(aClass_IActivityTaskManager.getClassLoader(), new Class[]{aClass_IActivityTaskManager}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        if ("startActivity".equals(method.getName())) {
                            Intent intent = getIntent(args);
                            if (ActivityInterceptor.startActivityInterceptor != null) {
                                if (ActivityInterceptor.startActivityInterceptor.isInterceptor(mInstant,method,args,intent)) {
                                    return 0;
                                }
                            }
                        }
                        return method.invoke(mInstant, args);
                    }
                });
                field_mInstance.set(iActivityTaskManagerSingleton, mInstantProxy);

            } catch
            (ClassNotFoundException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | NoSuchFieldException
                            e) {
                e.printStackTrace();
            }
        } else {
            try {
                Class<?> aClass = Class.forName("android.app.ActivityManager");
                Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityManagerSingleton");
                field_IActivityTaskManagerSingleton.setAccessible(true);
                Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);

                Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                field_mInstance.setAccessible(true);
                Method method_get = aClass_Singleton.getDeclaredMethod("get");
                Object mInstant = method_get.invoke(iActivityTaskManagerSingleton);
                mObject = mInstant;
                Class<?> aClass_IActivityManager = Class.forName("android.app.IActivityManager");
                Object mInstantProxy = Proxy.newProxyInstance(aClass_IActivityManager.getClassLoader(), new Class[]{aClass_IActivityManager}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


                        if ("startActivity".equals(method.getName())) {
                            Intent intent = getIntent(args);
                            if (ActivityInterceptor.startActivityInterceptor != null) {
                                if (ActivityInterceptor.startActivityInterceptor.isInterceptor(mInstant,method,args,intent)) {
                                    return 0;
                                }
                            }
                        }
                        return method.invoke(mInstant, args);
                    }
                });

                field_mInstance.set(iActivityTaskManagerSingleton, mInstantProxy);

            } catch
            (ClassNotFoundException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | NoSuchFieldException
                            e) {
                e.printStackTrace();
            }

        }

    }

    private static Intent getIntent(Object[] args){
        for (Object arg : args) {
            if (arg instanceof Intent) {
                return (Intent) arg;
            }
        }
        return null;
    }

    /**
     * 取消拦截
     */
    public synchronized static void unHook() {
        if (isHooked && mObject != null) {
            isHooked = false;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                try {
                    Class<?> aClass = Class.forName("android.app.ActivityTaskManager");
                    Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityTaskManagerSingleton");
                    field_IActivityTaskManagerSingleton.setAccessible(true);
                    Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);

                    Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                    Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                    field_mInstance.setAccessible(true);
                    field_mInstance.set(iActivityTaskManagerSingleton, mObject);

                } catch
                (ClassNotFoundException | IllegalAccessException | NoSuchFieldException
                                e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    Class<?> aClass = Class.forName("android.app.ActivityManager");
                    Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityManagerSingleton");
                    field_IActivityTaskManagerSingleton.setAccessible(true);
                    Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);
                    Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                    Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                    field_mInstance.setAccessible(true);
                    field_mInstance.set(iActivityTaskManagerSingleton, mObject);

                } catch
                (ClassNotFoundException | IllegalAccessException | NoSuchFieldException
                                e) {
                    e.printStackTrace();
                }

            }


        }

    }

    public interface IntentInterceptor {
        /**
         * ture为拦截startActivity启动
         * @param intent
         * @return
         */
        boolean isInterceptor(Object proxy, Method method, Object[] args,Intent intent);
    }

    public static class ListIntentInterceptor implements IntentInterceptor{
        private List<IntentInterceptor> list=new ArrayList<>();

        public void addIntentInterceptor(IntentInterceptor intentInterceptor){
            list.add(intentInterceptor);
        }

        public void removeIntentInterceptor(IntentInterceptor intentInterceptor){
            list.remove(intentInterceptor);
        }

        @Override
        public boolean isInterceptor(Object proxy, Method method, Object[] args, Intent intent) {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).isInterceptor(proxy, method, args, intent)){
                    return true;
                }
            }
            return false;
        }
    }
}
